package com.liuzh.kaoyanspringboot.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.liuzh.kaoyanspringboot.common.Constants;
import com.liuzh.kaoyanspringboot.common.Result;
import com.liuzh.kaoyanspringboot.config.AuthAccess;
import com.liuzh.kaoyanspringboot.entity.Files;

import com.liuzh.kaoyanspringboot.entity.User;
import com.liuzh.kaoyanspringboot.service.FileService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * <p>
 *  文件上传相关接口
 * </p>
 *
 * @author 刘志鸿
 * @since 2023-02-25
 */
@RestController
@RequestMapping("/file")
public class FileController {

    @Value("${files.upload.path}")
    private String fileUploadPath;
    @Autowired
    private FileService fileService;
    @AuthAccess
    @RequestMapping("/upload")
    public String upload(@RequestParam MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String type = FileUtil.extName(originalFilename);  // 获取文件类型
        long size = file.getSize();
        // 定义一个文件唯一的标识码
        String uuid = IdUtil.fastSimpleUUID();
        String fileUUID = "liuzh_" + uuid + StrUtil.DOT + type;
        File uploadFile = new File(fileUploadPath + fileUUID);

        // 存磁盘
        File uploadParentFile = new File(fileUploadPath);
        //判断配置的文件目录是否存在，无则新建
        if (!uploadParentFile.exists()) {
            uploadParentFile.mkdir();
        }

        file.transferTo(uploadFile);// 上传到磁盘
        //获取文件 md5
        String md5 = SecureUtil.md5(uploadFile);
        // 从数据库里查询是否有相同记录
        Files dbFiles = fileService.getFileByMd5(md5);   // 若 url 为空则说明数据库无记录
        String url;
        // 把获取到的文件存储到磁盘目录
        if (dbFiles == null) {  // 判断磁盘未有该文件，则存入磁盘
            url = "http://localhost:9090/file/" + fileUUID;
        } else {
            url = dbFiles.getUrl();
            uploadFile.delete();
        }

        // 储存数据库
        Files saveFile = new Files();
        saveFile.setName(originalFilename);
        saveFile.setType(type);
        saveFile.setSize(size/1024+ (size % 1024 != 0 ? 1 : 0));
        saveFile.setUrl(url);
        saveFile.setMd5(md5);
        fileService.save(saveFile);

        return url;
    }
    @AuthAccess
    @GetMapping("/{fileUUID}")
    public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        String  url = "http://localhost:9090/file/" + fileUUID;
//        fileService.isEnableByUrl(url);
        // 根据唯一标识码获取文件
        File downloadFile = new File(fileUploadPath + fileUUID);
        // 设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID,"UTF-8"));
        response.setContentType("application/octet-stream");
        // 读取文件字节流
        os.write((FileUtil.readBytes(downloadFile)));
        os.flush();
        os.close();
    }

    /**
     * 分页查询接口
     * @param pageNum
     * @param pageSize
     * @param name
     * @param size
     * @return
     */
    @GetMapping("/page")
    public Result findPage(@RequestParam Integer pageNum,
                           @RequestParam Integer pageSize,
                           @RequestParam(defaultValue = "") String name,
                           @RequestParam(defaultValue = "") String size) {
        IPage<Files> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        if(!"".equals(name)){
            queryWrapper.like("name",name);
        }
        if(!"".equals(size)){
            queryWrapper.like("size",size);
        }
        return Result.success(fileService.page(page, queryWrapper));
    }

    // 新增或更新
    @PostMapping("/update")
    public Result save(@RequestBody Files file) {
        return Result.success(fileService.saveOrUpdate(file));
    }

    // 根据 id 删除
    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable Integer id) {
        Files file = fileService.getById(id);
        String md5 = file.getMd5();
        String fileUUID = StringUtils.substring(file.getUrl(),27);
        if (fileService.removeById(id)) {
            QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("md5",md5);
            int count = (int) fileService.count(queryWrapper);
            if (count == 0) {
                // 根据唯一标识码获取文件
                File deleteFile = new File(fileUploadPath + fileUUID);
                deleteFile.delete();
            }
            return Result.success();
        }
        return Result.error(Constants.CODE_500,"系统错误");

    }

    // 批量删除
    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids) {
        return Result.success(fileService.removeBatchByIds(ids));
    }

    @AuthAccess
    @GetMapping("/front/all")
    public Result frontAll() {
        return Result.success(fileService.list());
    }

}
